<template>
  <div class="g-card-list">
    <!-- 搜索表单区域，支持通过 slot 自定义 -->
    <el-card class="search-card" v-if="showSearchForm">
      <slot name="search-form" :queryData="queryData" :handleQuery="handleQuery" :resetQuery="resetQuery">
        <!-- 默认搜索表单 -->
        <el-form :model="queryData" ref="queryForm" :inline="true" label-width="80px">
          <el-form-item label="关键字">
            <el-input v-model="queryData.keyword" placeholder="请输入关键字" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleQuery">查询</el-button>
            <el-button @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>
      </slot>
    </el-card>

    <!-- 卡片列表区域 -->
    <el-row :gutter="20" v-loading="loading">
      <el-col v-for="(item, index) in displayData" :key="index" :span="6">
        <el-card class="box-card" shadow="always">
          <!-- 卡片头部，支持通过 slot 自定义 -->
          <template #header>
            <slot name="card-header" :item="item" :index="index">
              <!-- 默认卡片头部 -->
              <div class="card-header">
                <span>{{ item.title || '标题' }}</span>
              </div>
            </slot>
          </template>

          <!-- 卡片主体，支持通过 slot 自定义 -->
          <slot name="card-body" :item="item" :index="index">
            <!-- 默认卡片主体 -->
            <div class="card-body">
              <p>{{ item.description || '暂无描述' }}</p>
            </div>
          </slot>

          <!-- 卡片底部，支持通过 slot 自定义 -->
          <template #footer>
            <slot name="card-footer" :item="item" :index="index">
              <!-- 默认卡片底部 -->
              <div class="card-footer">
                <el-button type="primary" size="small">操作</el-button>
              </div>
            </slot>
          </template>
        </el-card>
      </el-col>
    </el-row>

    <!-- 分页组件 -->
    <el-pagination
      v-if="showPagination"
      background
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      :page-size="queryData.pageSize"
      :current-page="queryData.pageNum"
      :page-sizes="[12, 24, 36, 48]"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script setup>
import { ref, onMounted, watch, computed } from 'vue'
import axios from 'axios'

// 定义组件属性
const props = defineProps({
  // 数据API地址
  dataApi: {
    type: String,
    default: ''
  },
  // 直接传入的数据
  data: {
    type: Array,
    default: () => []
  },
  // 是否显示搜索表单
  showSearchForm: {
    type: Boolean,
    default: true
  },
  // 是否显示分页
  showPagination: {
    type: Boolean,
    default: true
  }
})

// 定义事件
const emit = defineEmits(['update:data'])

// 响应式数据
const loading = ref(false)
const total = ref(0)
const queryData = ref({
  pageNum: 1,
  pageSize: 12,
  keyword: ''
})

// 计算显示的数据（支持筛选和分页）
const displayData = computed(() => {
  // 如果使用 API 获取数据，则直接返回 dataList
  if (props.dataApi) {
    return dataList.value
  }
  
  // 如果使用传入的数据，则进行筛选
  let filteredData = [...props.data]
  
  // 根据查询条件筛选（排除分页相关的字段）
  const excludeFields = ['pageNum', 'pageSize']
  Object.keys(queryData.value).forEach(key => {
    // 跳过分页相关字段和空值
    if (excludeFields.includes(key) || !queryData.value[key]) {
      return
    }
    
    // 获取查询值并转为小写
    const queryValue = String(queryData.value[key]).toLowerCase()
    
    // 根据字段名进行精确筛选
    filteredData = filteredData.filter(item => {
      // 如果对象有这个字段，则进行匹配
      if (item.hasOwnProperty(key)) {
        return String(item[key]).toLowerCase().includes(queryValue)
      }
      // 如果没有这个字段，则保留所有数据（或者根据需要可以排除）
      return true
    })
  })
  
  // 更新总数量
  total.value = filteredData.length
  
  // 分页处理
  if (props.showPagination) {
    const start = (queryData.value.pageNum - 1) * queryData.value.pageSize
    const end = start + queryData.value.pageSize
    return filteredData.slice(start, end)
  }
  
  return filteredData
})

const dataList = ref([])

// 查询方法
const handleQuery = () => {
  if (props.dataApi) {
    fetchData()
  } else {
    // 对于传入的数据，重置页码为第一页
    queryData.value.pageNum = 1
  }
}

// 重置查询
const resetQuery = () => {
  queryData.value = {
    pageNum: 1,
    pageSize: 12,
    keyword: ''
  }
  handleQuery()
}

// 处理分页大小改变
const handleSizeChange = (val) => {
  queryData.value.pageSize = val
  queryData.value.pageNum = 1
  handleQuery()
}

// 处理当前页改变
const handleCurrentChange = (val) => {
  queryData.value.pageNum = val
  handleQuery()
}

// 从API获取数据
const fetchData = async () => {
  if (!props.dataApi) return

  loading.value = true
  try {    
    const response = await axios.get(props.dataApi, {
      params: queryData.value
    })
    
    if (response.data) {
      // 假设API返回的数据结构为 { total: number, data: array }
      dataList.value = response.data.data || response.data
      total.value = response.data.total || response.data.length
    }
  } catch (error) {
    console.error('获取数据失败:', error)
  } finally {
    loading.value = false
  }
}

// 监听传入的data变化
watch(
  () => props.data,
  (newData) => {
    // 更新总数量
    total.value = newData.length
  },
  { immediate: true }
)

// 组件挂载时获取数据
onMounted(() => {
  if (props.dataApi) {
    fetchData()
  } else if (props.data && props.data.length) {
    dataList.value = props.data
    total.value = props.data.length
  }
})

// 如果同时提供了dataApi和data，则优先使用dataApi
</script>

<style scoped lang="scss">
.g-card-list {
  padding: 15px;
}

.search-card {
  margin-bottom: 15px;
}

.box-card {
  margin-bottom: 20px;
  
  :deep(.el-card__header) {
    padding: 10px 20px;
    border-bottom: 1px solid #ebeef5;
  }
  
  :deep(.el-card__body) {
    padding: 20px;
    min-height: 120px;
  }
  
  :deep(.el-card__footer) {
    padding: 10px 20px;
    border-top: 1px solid #ebeef5;
    text-align: right;
  }
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-body {
  p {
    margin: 0;
    color: #666;
    line-height: 1.5;
  }
}

.card-footer {
  display: flex;
  justify-content: flex-end;
}

.el-pagination {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}
</style>